﻿using System;
using System.Collections;
using fit;
using fitlibrary;
using StoryTeller.FixtureModel;

namespace SCSoft.WinForms.Tests
{
    public class BoundScreenFixture : DoFixture
    {
        private ITestDriver _driver;
        private MockMessageBoxCreator _messageBoxCreator;

        public ITestDriver Driver
        {
            get 
            { 
                if( _driver == null )
                {
                    throw new ApplicationException(String.Format(
                                                       "The driver property is null for bound screen fixture '{0}'. " +
                                                       "This is usually due to the fact that you need to add a partial class file with " +
                                                       "a default constructor that assigns the Driver property and, optionally the " +
                                                       "MessageBoxCreator property of the BoundScreenFixture base class.",
                                                       GetType().Name));
                }
                return _driver; 
            }
            set { _driver = value; }
        }


        public MockMessageBoxCreator MessageBoxCreator
        {
            get { return _messageBoxCreator; }
            set { _messageBoxCreator = value; }
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="label"></param>
        /// <example>|Click|[label]|</example>
        [Example("|Click|[label]|")]
        public void Click(string label)
        {
            Driver.Click(label);
        }

        [Example("|Click|[label]|and expect dialog|[caption]|")]
        public void ClickAndExpectDialog(string label, string caption)
        {
            using (_messageBoxCreator.Verification())
            {
                _messageBoxCreator.ExpectMessage(caption, null);
                Driver.Click(label);
            }
        }

        [Example("|Click|[label]|and answer|[true/false]|to dialog|[caption]|")]
        public void ClickAndAnswerToDialog(string label, bool returnValue, string caption)
        {
            using (_messageBoxCreator.Verification())
            {
                _messageBoxCreator.ExpectPrompt(caption, null, returnValue);
                Driver.Click(label);
            }
        }


        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
        /// <example>
        /// |Check the Screen State|
        /// |Element Name|Is Enabled()|Is Visible()|
        /// |[element1]  |true/false  |true/false  |
        /// </example>
        [Example(
            @"|Check the Screen State|
|Element Name|Is Enabled()|Is Visible()|
|[element1]  |true/false  |true/false  |
"
            )]
        public Fixture CheckTheScreenState()
        {
            return new ScreenElementStateFixture(Driver);
        }


        /// <summary>
        /// 
        /// </summary>
        /// <param name="label"></param>
        /// <returns></returns>
        /// <example>|Check|The Focus is on|[label]|</example>
        [Example("|Check|The Focus is on|[label]|")]
        public bool TheFocusIsOn(string label)
        {
            return Driver.IsFocused(label);
        }

        /// <summary>
        /// 
        /// </summary>
        /// <example>|Tab off current field|</example>
        [Example("|Tab off|[label]|")]
        public void TabOff(string label)
        {
            Driver.TabOffOf(label);
        }

        [Example("|Tab Off|[label]|and expect dialog|[caption]|")]
        public void TabOffAndExpectDialog(string label, string caption)
        {
            using (_messageBoxCreator.Verification())
            {
                _messageBoxCreator.ExpectMessage(caption, null);
                Driver.TabOffOf(label);
            }
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="text"></param>
        /// <param name="label"></param>
        /// <example>|Enter|[text]|for|[label]|</example>
        [Example("|Enter|[text]|for|[label]|")]
        public void EnterFor(string text, string label)
        {
            Driver.Enter(label, text);
        }

        [Example("|Enter|[text]|for|[label]|and expect dialog|[caption]|")]
        public void EnterForAndExpectDialog(string text, string label, string caption)
        {
            using (_messageBoxCreator.Verification())
            {
                _messageBoxCreator.ExpectMessage(caption, null);
                Driver.Enter(label, text);
            }
        }

        [Example("|Enter date|[date]|for|[label]|")]
        public void EnterDateFor(string dateString, string label)
        {
            Driver.EnterDate(label, dateString);
        }

        [Example("|Enter date|[date]|for|[label]|and expect dialog|[caption]|")]
        public bool EnterDateForAndExpectDialog(string dateString, string label, string caption)
        {
            using (_messageBoxCreator.Verification())
            {
                _messageBoxCreator.ExpectMessage(caption, null);
                Driver.EnterDate(label, dateString);
            }

            return true;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="display"></param>
        /// <param name="label"></param>
        /// <example>|Select|[display]|for|[label]|</example>
        [Example("|Select|[display]|for|[label]|")]
        public void SelectFor(string display, string label)
        {
            Driver.Select(label, display);
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="label"></param>
        /// <returns></returns>
        /// <example>|Check|The value of|[label]|is|[expected]|</example>
        [Example("|Check|The value of|[label]|is|[expected]|")]
        public object TheValueOfIs(string label)
        {
            return Driver.GetValue(label);
        }

        [Example("|Check|The date for|[label]|is|[date]|")]
        public DateTime TheDateForIs(string label)
        {
            return Driver.GetDate(label);
        }

        [Example("|The date for|[label]|is blank|")]
        public bool TheDateForIsBlank(string label)
        {
            return Driver.DateIsBlank(label);
        }

        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
        /// <example>|Check|That field|[label]|is checked|true/false|</example>
        [Example("|Check|That field|[label]|is checked|true/false|")]
        public bool ThatFieldIsChecked(string label)
        {
            return Driver.IsChecked(label);
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="label"></param>
        /// <returns></returns>
        /// <example>|Verify the list of |[label]|is|
        /// |[Col1]|
        /// |[Val1]|</example>
        [Example(@"|Verify the list of |[label]|is|
|[Col1]|
|[Val1]|
")]
        public Fixture VerifyTheListOfIs(string label)
        {
            IList list = Driver.GetListFor(label);
            if (list.Count == 0)
            {
                return new BasicRowFixture(new object[0]);
            }

            object[] array = new object[list.Count];

            if (list[0].GetType().IsEnum)
            {
                for (int i = 0; i < array.Length; i++)
                {
                    array[i] = new StringValue(){Value = list[i].ToString()};                    
                }
            }
            else
            {
                list.CopyTo(array, 0);
            }

            return new BasicRowFixture(array);
        }

        [Example("No dialogs were shown")]
        public bool NoDialogsWereShown()
        {
            return true;
        }
    }
}